package mrpanyu.guitool.jasypt;

import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;

import mrpanyu.guitool.base.annotation.Action;
import mrpanyu.guitool.base.annotation.OnParameterChange;
import mrpanyu.guitool.base.annotation.Parameter;
import mrpanyu.guitool.base.annotation.ToolModel;
import mrpanyu.guitool.base.model.ParameterType;
import mrpanyu.guitool.base.model.Tool;

@ToolModel(displayName = "Jasypt加解密工具", description = "适用于jasypt-spring-boot-starter的加解密工具")
public class JasyptEncryptor {

	@Parameter(displayName = "操作", order = 0, type = ParameterType.SELECT, options = { "加密", "解密" })
	private String operation;

	@Parameter(displayName = "密钥", order = 1, type = ParameterType.TEXT)
	private String password;

	@Parameter(displayName = "原值", order = 2, type = ParameterType.TEXT)
	private String value;

	@Parameter(displayName = "加密值", order = 3, type = ParameterType.TEXT, visible = false)
	private String encrypted = "ENC(XXXXXXXXXX)";

	@OnParameterChange("operation")
	public void onOperationChange(Tool tool) {
		if ("加密".equals(operation)) {
			tool.getParameter("value").setVisible(true);
			tool.getParameter("encrypted").setVisible(false);
			tool.getAction("encrypt").setVisible(true);
			tool.getAction("decrypt").setVisible(false);
		} else {
			tool.getParameter("value").setVisible(false);
			tool.getParameter("encrypted").setVisible(true);
			tool.getAction("encrypt").setVisible(false);
			tool.getAction("decrypt").setVisible(true);
		}
	}

	@Action(displayName = "加密", order = 0)
	public void encrypt(Tool tool) {
		try {
			String encrypted = encryptor().encrypt(value);
			encrypted = "ENC(" + encrypted + ")";
			tool.infoMessage(encrypted);
		} catch (Exception e) {
			e.printStackTrace();
			tool.errorMessage(e);
		}
	}

	@Action(displayName = "解密", order = 1, visible = false)
	public void decrypt(Tool tool) {
		try {
			String encrypted = this.encrypted.trim();
			if (encrypted.startsWith("ENC(")) {
				encrypted = encrypted.substring(4, encrypted.lastIndexOf(')'));
			}
			String value = encryptor().decrypt(encrypted);
			tool.infoMessage(value);
		} catch (Exception e) {
			e.printStackTrace();
			tool.errorMessage(e);
		}
	}

	@Action(displayName = "清空", order = 2)
	public void clear(Tool tool) {
		tool.clearMessages();
	}

	private PooledPBEStringEncryptor encryptor() {
		PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
		SimpleStringPBEConfig config = new SimpleStringPBEConfig();
		config.setPassword(password);
		config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
		config.setKeyObtentionIterations("1000");
		config.setPoolSize("1");
		config.setProviderName("SunJCE");
		config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
		config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
		config.setStringOutputType("base64");
		encryptor.setConfig(config);
		return encryptor;
	}

}
